-
Notifications
You must be signed in to change notification settings - Fork 29
Add GetPlatformInfo action
#32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
|
@googlebot I signed it! |
|
CLAs look good, thanks! ℹ️ Googlers: Go here for more info. |
src/action/platform_info.rs
Outdated
| extern crate sys_info; | ||
|
|
||
| /// Using for `uname` syscall. | ||
| extern crate libc; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need these declarations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need now, I removed them.
src/action/platform_info.rs
Outdated
| CannotGetOSType(ref error) => { | ||
| write!(fmt, "can't get OS type error: {}", error) | ||
| }, | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excessive blank line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!
Cargo.toml
Outdated
| @@ -15,3 +15,4 @@ rrg-proto = { path = "proto/" } | |||
| simplelog = { version = "0.7.6" } | |||
| structopt = { version = "0.3.12" } | |||
| sys-info = { version = "0.5.1" } | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recently, I have made a change to use the sysinfo crate rather than sys-info. sys-info does not seem to work on other operating systems and is more low-level, whereas sysinfo gives you more abstractions and works on pretty much all supported platforms and saves us from having a lot of unsafe calls. Have you considered using it?
Right now, the code will not compile on Windows and macOS, I believe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I try to find something useful for my action in crate sysinfo, but, seems to me, this package doesn't provide any information about OS, only about system at all.
Also as documentation of sys-info says that it supports Windows and Mac OS too.
src/action/platform_info.rs
Outdated
| /// A Response type for `GetPlatformInfo` action | ||
| pub struct Response { | ||
| /// Client platform information | ||
| platform_information: PlatformInfo, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to have separate types PlatformInfo and Response (that is specific to an action called GetPlatformInfo)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason, now fixed:)
src/action/platform_info.rs
Outdated
| } | ||
|
|
||
| /// Funcion that converts raw C-strings into `String` type | ||
| #[inline(always)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason for forcing inlinining over letting the compiler decide (or a slightly less "demanding" variant: just #[inline])?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that it would be nice if the conversion code was inlined, but probably this solution should be left to the compiler. Thanks!
src/action/platform_info.rs
Outdated
| system: Option<String>, | ||
| release_name: Option<String>, | ||
| version_id: Option<String>, | ||
| machine: Option<String>, | ||
| kernel_release: Option<String>, | ||
| fqdn: Option<String>, | ||
| architecture: Option<String>, | ||
| node: Option<String> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like a lot of these variants would benefit from having a dedicated enum rather than using raw strings for everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand, what do you mean by dedicated enum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, for system you could have an enum with Linux, Windows etc. But this might not be ideal solution as it might break on some awkward platforms (that we don't really support, but who knows). On the other hand, passing through library-dependent values is not great either as we bind semantics of our protocol to some third-party internal details. In the end, I think it is fine to leave it as it is, I might look into that in the future.
src/action/mod.rs
Outdated
| //! instance of the corresponding request type and send some (zero or more) | ||
| //! instances of the corresponding response type. | ||
|
|
||
| pub mod platform_info; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just platform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't work, because my file is named platform_info.rs and if I change platform_info to platform I get compilation error. Or, maybe, I don't understand you correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, you should rename the module (both the file and this line) to be just platform.
src/action/platform_info.rs
Outdated
| #[cfg(target_os = "linux")] | ||
| use libc::{uname, utsname}; | ||
| use libc::c_char; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to put platform-specific imports locally next to the places that actually need them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thanks! Fixed.
src/action/platform_info.rs
Outdated
| system: self.system.clone(), | ||
| release: self.release_name.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to clone? into_proto takes an owned response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to clone, because pep425tag also try to move these fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? You are just stringifying them, borrowing them should be enough. You probably need to refactor it to a separate variable.
src/action/platform_info.rs
Outdated
| machine: self.machine, | ||
| kernel: self.kernel_release, | ||
| fqdn: self.fqdn, | ||
| architecture: self.architecture.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
src/action/platform_info.rs
Outdated
| pep425tag: Some( | ||
| format!("{}_{}_{}", | ||
| self.system.unwrap_or(String::from("")), | ||
| self.release_name.unwrap_or(String::from("")), | ||
| self.architecture.unwrap_or(String::from("")) | ||
| )), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If any of these values is None you could end up with something like foo__bar or _foo_. Is this expected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to fill this field by analogy with the Python code, but forgot that None converts to 'None' in Python. Thanks!
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod test { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests mostly re-implement the implementation, which makes them quite useless (or even dangerous). In most cases, its of course impossible to write proper tests, so I think it is just better to assert that the values are non-empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, understand, thanks!
src/action/mod.rs
Outdated
| //! instance of the corresponding request type and send some (zero or more) | ||
| //! instances of the corresponding response type. | ||
|
|
||
| pub mod platform_info; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, you should rename the module (both the file and this line) to be just platform.
src/action/platform_info.rs
Outdated
| system: self.system.clone(), | ||
| release: self.release_name.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? You are just stringifying them, borrowing them should be enough. You probably need to refactor it to a separate variable.
src/action/platform_info.rs
Outdated
| fn test_system() { | ||
| let mut session = session::test::Fake::new(); | ||
| assert!(handle(&mut session, ()).is_ok()); | ||
|
|
||
| assert_eq!(session.reply_count(), 1); | ||
| let platform_info = &session.reply::<Response>(0); | ||
|
|
||
| assert!(platform_info.system.is_some()); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this test you could actually have platform-specific test cases for every supported platform (through #[cfg_attr(..., ignore)]) that actually test this field for some specific values (e.g. "Linux").
src/action/platform_info.rs
Outdated
| system: Option<String>, | ||
| release_name: Option<String>, | ||
| version_id: Option<String>, | ||
| machine: Option<String>, | ||
| kernel_release: Option<String>, | ||
| fqdn: Option<String>, | ||
| architecture: Option<String>, | ||
| node: Option<String> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, for system you could have an enum with Linux, Windows etc. But this might not be ideal solution as it might break on some awkward platforms (that we don't really support, but who knows). On the other hand, passing through library-dependent values is not great either as we bind semantics of our protocol to some third-party internal details. In the end, I think it is fine to leave it as it is, I might look into that in the future.
src/action/platform_info.rs
Outdated
| } | ||
| } | ||
|
|
||
| /// A Response type for `GetPlatformInfo` action |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Response" should not be uppercase here, there should be a dot at the end of the comment.
src/action/platform_info.rs
Outdated
| /// Client platform information | ||
| system: Option<String>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This documentation item looks like something that applies to the whole struct, not only to the system field.
src/action/platform_info.rs
Outdated
| "Linux" => { | ||
| get_linux_response(session, os_type)?; | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a good candidate for conditional compilation rather than some run-time behaviour that depends on what the third-party library decides to return.
This pull request implements the
GetPlatformInfoaction, closes #6.I left
libc_verandinstall_datefields blank because functionUname.FromCurrentSystem(link) doesn't fill them. I also add libc crate which providesunamesystem call.All fields, except
libc_verandinstall_date, are currently filled for Linux.